#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <numeric>
#include <vector>
#include <iterator>
#include <functional>
#include <boost/bind.hpp>
#include <boost/timer.hpp>
#include <boost/shared_ptr.hpp>

using namespace std;

struct A{
	virtual void f() = 0;
};

struct B:public A{
	virtual void f(){
		cout<<"B::f()"<<endl;
	}
};

struct C:public A{
	virtual void f(){
		cout<<"C::f()"<<endl;
	}
};

struct D:public A{
	virtual void f(){
		cout<<"D::f()"<<endl;
	}
};

int main(int argc, char** argv)
{
	srand( static_cast<int>(time(0)) );
	typedef boost::shared_ptr<A> SPA;
	typedef boost::shared_ptr<B> SPB;
	typedef boost::shared_ptr<C> SPC;
	typedef boost::shared_ptr<D> SPD;

	vector<A*> VA;
	vector<B*> VB;
	vector<C*> VC;
	vector<D*> VD;

	for(int i=0;i<100;++i)
	{
		switch (rand()%3)
		{
			case 0:
				VA.push_back( new B );
				break;
			case 1:
				VA.push_back( new C );
				break;
			case 2:
				VA.push_back( new D );
				break;
		}
	}

	vector<A*>::iterator pos = VA.begin();
	for(;pos!=VA.end();++pos)
	{
		B* pb = dynamic_cast<B*>(*pos);
		C* pc = dynamic_cast<C*>(*pos);
		D* pd = dynamic_cast<D*>(*pos);

		if(pb)
			VB.push_back(pb);
		else if(pc)
			VC.push_back(pc);
		else if(pd)
			VD.push_back(pd);
	}

	cout<<"A*  <->  "<<VA.size()<<endl;
	cout<<"B*  <->  "<<VB.size()<<endl;
	cout<<"C*  <->  "<<VC.size()<<endl;
	cout<<"D*  <->  "<<VD.size()<<endl;

	return 0;
}
